package com.ruoyi.bl.tools;
import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;

import com.alibaba.dashscope.app.Application;
import com.alibaba.dashscope.app.ApplicationParam;
import com.alibaba.dashscope.app.ApplicationResult;
import com.ruoyi.bl.domain.BlUser;
import com.ruoyi.bl.domain.MemoryId;
import com.ruoyi.bl.service.MemoryIdService;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;

import io.reactivex.Flowable;
import lombok.extern.slf4j.Slf4j;

/**
 * 百炼智能体核心代码
 *
 * @Author:张浩
 * @Date:2023/3/1615:05
 * @Version1.0
 * @Description:通过inputValue输入问题,调用百炼接口,形成智能问答
 * @目前存在的问题:需要根据用户特定的memoryid来生成有针对性的问题回答
 */
@CrossOrigin(origins = "*")
@Slf4j
@RestController
@RequestMapping("/aliyun")
public class RequestAsk {
    @Autowired
    private MemoryIdService memoryIdService;
    /**
     * 调用百炼接口,生成智能问答
     * @param inputValue 用户输入提问
     * @return   返回流式输出
     * @throws Exception
     */
    @GetMapping("/ask")
    public ResponseBodyEmitter ask(@RequestParam String inputValue) throws Exception {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        BlUser user = (BlUser) loginUser.getUser();
        System.out.println(user);
        System.out.println("获取的id为" + user.getUserId());
        Long id = user.getUserId();
        MemoryId MemoryId = memoryIdService.queryMemoryId(id);
        String memoryId = MemoryId.getMemoryId();
        System.out.println("获取的memoryId为" + memoryId);
        // 设置超时时间和响应头
        ResponseBodyEmitter emitter = new ResponseBodyEmitter(-1L); // 无限超时
        // 设置响应头
        emitter.send("\n"); // 发送一个初始换行符以启动连接
        ApplicationParam param = ApplicationParam.builder()
                .apiKey("sk-dd83a9bc21f5440491fe836b7aa33cee")//主机的apikey
                .appId("36e4407638164b34b63cf588d956835f")//智能体应用id,后续需要调教一个优秀的智能体
                .prompt(inputValue)//prompt提示词
                .memoryId(memoryId)//用户特定id,通过用户登录账号,在数据库中找到唯一的memoryid
                .incrementalOutput(true)//是否使用流式输出,我记得是这个功能来着,有些忘记了
                .build();
        Application application = new Application();
        Flowable<ApplicationResult> result = application.streamCall(param);
        result.subscribe(
                data -> {
                    try {
                        String text = data.getOutput().getText();
                        System.out.println(text);
                        emitter.send(text);
                    } catch (IOException e) {
                        emitter.completeWithError(e);
                    }
                },
                error -> {
                    log.error("Stream error:", error);
                    emitter.completeWithError(error);
                },
                () -> {
                    try {
                        emitter.send("[DONE]");
                        emitter.complete();
                    } catch (IOException e) {
                        emitter.completeWithError(e);
                    }
                }
        );
        return emitter;
    }
}
